/*
 * GraphPanel.java
 *
 * Created on den 30 november 2007, 17:08
 */
package grex.Graphics;

import grex.Options;
import grex.Prediction;
import grex.genes.Gene;
import java.awt.Color;

import java.awt.Graphics;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.util.ArrayList;

/**
 *
 * @author  RIK
 */
public class MatrixPanel extends javax.swing.JPanel implements ComponentListener, IOutputPanel {

    private ArrayList<GPoint> gPoints;
    private ArrayList<GPoint> rPoints;
    private int nrOfTrains;
    private double xMax = Double.MIN_VALUE,  yMax = Double.MIN_VALUE,  xMin = Double.MAX_VALUE,  yMin = Double.MAX_VALUE;
    private Options ops;
    /** Creates new form GraphPanel */
    public MatrixPanel(Options ops) {
        initComponents();
       // setBackground(new java.awt.Color(227, 227, 227));
       // setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED), "Correct (Green), Error (Red), Correct if error (Black)"));
        this.addComponentListener(this);
        this.ops=ops;
    }

    public MatrixPanel(ArrayList<Prediction> train,ArrayList<Prediction> test,Options ops){      
        initComponents();
        this.addComponentListener(this);
        this.ops=ops;
        init(train,test);
    }

    public void init(ArrayList<Prediction> train,ArrayList<Prediction> test){      
        xMax=train.size()+test.size();
        yMax=Double.MIN_VALUE;
        xMin=0;
        yMin=Double.MAX_VALUE;
        double x,gY,rY;
        gPoints = new ArrayList<GPoint>();
        rPoints = new ArrayList<GPoint>();

        nrOfTrains = train.size();
        for(Prediction p:train){
            x=gPoints.size();
            gY=p.getPrediction();
            rY=p.getTargetValue();            
            if(gY>yMax)
                yMax=gY;
            if(gY<yMin)
                yMin=gY;
            if(rY>yMax)
                yMax=rY;
            if(rY<yMin)
                yMin=rY;
            gPoints.add(new GPoint(x,gY,p.getProbabillity(),p.getLowerProbabillity(),p.getGene(), false,p));
            rPoints.add(new GPoint(x,rY,p.getProbabillity(),p.getLowerProbabillity(),p.getGene(), true,p));
        }
        for(Prediction p:test){
            x=gPoints.size();
            gY=p.getPrediction();
            rY=p.getTargetValue();            
            if(gY>yMax)
                yMax=gY;
            if(gY<yMin)
                yMin=gY;
            if(rY>yMax)
                yMax=rY;
            if(rY<yMin)
                yMin=rY;
            gPoints.add(new GPoint(x,gY,p.getProbabillity(),p.getLowerProbabillity(),p.getGene(), false,p));
            rPoints.add(new GPoint(x,rY,p.getProbabillity(),p.getLowerProbabillity(),p.getGene(), true,p));
        }                         
        update();
    }

    public void update() {
        this.removeAll();
        addGraphPoints();
        validate();
        repaint();
    }

    public void addGraphPoints() {
        double x, y;
        if (gPoints != null) {
            int w = (int) gPoints.get(0).getSize().getHeight();
            for (GPoint p : gPoints) {
                x = Math.round((getWidth() - w) * ((p.getXValue() - xMin) / (xMax - xMin)));
                y = (int) Math.round(getHeight() - w - (getHeight() - w) * ((p.getYValue() - yMin) / (yMax - yMin)));
                add(p, new org.netbeans.lib.awtextra.AbsoluteConstraints((int) x, (int) y, -1, -1));
            //    p.setVisible(false);
            }
            for (GPoint p : rPoints) {
                x = Math.round((getWidth() - w) * ((p.getXValue() - xMin) / (xMax - xMin)));
                y = (int) Math.round(getHeight() - w - (getHeight() - w) * ((p.getYValue() - yMin) / (yMax - yMin)));
                add(p, new org.netbeans.lib.awtextra.AbsoluteConstraints((int) x, (int) y, -1, -1));
              //  p.setVisible(false);
            }
        }
    }
    public void highLightGraphPoints(Gene leaf, ArrayList<Gene> leafs) {
        for (int i = 0; i < gPoints.size(); i++) {
            gPoints.get(i).setVisible(false);
            //gPoints.get(i).highLigt(leafs.get(i).equals(leaf));

        }
          repaint();
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        GPoint g1, g2;
        int w = 0;
        if (gPoints != null) {
            g.setColor(Color.red);
            
            double xSquares = gPoints.size();
            double ySqaures = gPoints.get(0).getPrediction().getProbs().length;
            double yS = getHeight()/ySqaures;
            double xS = getWidth()/xSquares;
            

            for(int x= 0; x<xSquares-1;x++){
                for(int c = 0;c<ySqaures;c++){
                    Prediction p= gPoints.get(x).getPrediction();                                     
                    
                    if(p.getTargetValue()!=p.getPrediction()&&p.getTargetValue()==c){
                        g.setColor(new Color(1,(float)p.getProbForClass(c),(float) p.getProbForClass(c)));
                        //g.setColor(Color.BLACK);
                    }else if(p.getTargetValue()==p.getPrediction()&&p.getPrediction()==c){
                        //g.setColor(new Color((float)0,(float) p.getProbForClass(c),(float) 0));
                        g.setColor(new Color(1-(float) p.getProbForClass(c),1,1-(float) p.getProbForClass(c)));
                    } else{
                       // g.setColor(new Color((float)p.getProbForClass(c),(float) 0,(float) 0));
                        g.setColor(new Color(1,1-(float)p.getProbForClass(c),1-(float)p.getProbForClass(c)));
                    }
                    g.fillRect((int) (x*xS), (int)(c*yS), (int)((x+1)*xS)-1,(int) ((c+1)*yS)-1);
                    if(p.getTargetValue()==c && xSquares*3 < getWidth()){
                        g.setColor(Color.BLACK);
                        g.drawRect((int) (x*xS), (int)(c*yS), (int)((x+1)*xS)-1,(int) ((c+1)*yS)-1);
                    }
                    if(x==nrOfTrains){
                        g.setColor(Color.BLACK);
                        g.fillRect((int) (x*xS)-3, 0, 3, getHeight());
                    }
                }
            } 
            
           /* 
            for(int x= 0; x<xSquares-1;x++){
                for(int c = 0;c<ySqaures;c++){
                    Prediction p= gPoints.get(x).getPrediction();                                                         
                    if(p.getTargetValue()==c){
                        g.setColor(Color.BLACK);
                        g.drawRect((int) (x*xS), (int)(c*yS), (int)((x+1)*xS),(int) ((c+1)*yS));
                    }
                    if(x==nrOfTrains){
                        g.setColor(Color.BLACK);
                        g.fillRect((int) (x*xS), 0, 2, getHeight());
                    }
                }
            }*/
            
       /*     
            w = ((int) getComponent(0).getSize().getWidth()) / 2;
            for (int i = 1; i < gPoints.size(); i++) {
                g1 = gPoints.get(i - 1);
                g2 = gPoints.get(i);
                g.setColor(g1.getForeground());
                g.drawLine(g1.getX() + w, g1.getY() + w, g2.getX() + w, g2.getY() + w);
                if (i == nrOfTrains) {
                    g.setColor(Color.black);
                    g.fillRect(g2.getX() + w + w, 0, 3, this.getHeight());
                }
            }
            for (int i = 1; i < rPoints.size(); i++) {
                g1 = rPoints.get(i - 1);
                g2 = rPoints.get(i);
                g.setColor(g1.getForeground());
                g.drawLine(g1.getX() + w, g1.getY() + w, g2.getX() + w, g2.getY() + w);
            }*/
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());
    }// </editor-fold>                        
    public void componentResized(ComponentEvent e) {
        update();
    }

    public void componentMoved(ComponentEvent e) {
    //  throw new UnsupportedOperationException("Not supported yet.");
    }

    public void componentShown(ComponentEvent e) {
    //    throw new UnsupportedOperationException("Not supported yet.");
    }

    public void componentHidden(ComponentEvent e) {
    //     throw new UnsupportedOperationException("Not supported yet.");
    }
    // Variables declaration - do not modify                     
    // End of variables declaration                   
}
